package gopl

import (
	"strconv"
)

var pc [256]byte = func() (pc [256]byte) {
	for i := range pc {
		pc[i] = pc[i/2] + byte(i&1)
	}
	return
}()

// 形参interface{}可接受任何类型参数
func PopCount(value interface{}) int {

	x := typeConvert(value)

	return int(pc[byte(x>>(0*8))] +
		pc[byte(x>>(1*8))] +
		pc[byte(x>>(2*8))] +
		pc[byte(x>>(3*8))] +
		pc[byte(x>>(4*8))] +
		pc[byte(x>>(5*8))] +
		pc[byte(x>>(6*8))] +
		pc[byte(x>>(7*8))])
}

// rerutn interface{} 可返回任意类型值
// 反射也可以获取变量类型：fmt.Println("type:", reflect.TypeOf(x))
func typeConvert(x interface{}) (res uint64) {
	switch v := x.(type) { // x.(type)只能在switch使用
	case string:
		u, _ := strconv.ParseUint(v, 10, 64)
		res = u
	// 此处可确定x是string 所以switch后面不写了
	case int:
		res = uint64(v)
	}
	return res
}
